


/**
 * Time接收的时间戳都是以毫秒为单位的，服务器传过来的是秒，注意转化。
 */
export default class TimeHelper {
    static s_DeltaTime = 0;// 本地时间戳与服务器时间戳的差值。
    static s_CurTimeZone = null;    //本地时区 UTC+? 相对UTC时间多出的时区数
    static s_ServerTimeZone = 8;    //服务器时区 UTC+8 相对UTC时间多出的时区数

    /**
     * serverTime必须精确到毫秒
     * @param serverTime 登录服务器的时间戳 毫秒
     * @param zoneOffset 服务器的时区 秒
     */
    static sync(serverTime, zoneOffset?) {
        this.s_DeltaTime = serverTime - this.localNow();
        if (zoneOffset) {
            this.s_ServerTimeZone = zoneOffset / 3600;
        }

        this.s_CurTimeZone = 0 - new Date().getTimezoneOffset() / 60;
        // cc.log(" this.s_DeltaTime  ",this.s_DeltaTime," s_ServerTimeZone ",this.s_ServerTimeZone," s_CurTimeZone ",this.s_CurTimeZone," zoneOffset ",zoneOffset);
    }

    //返回服务器时间(精确到毫秒的时间戳)
    static now() {
        return this.localNow() + this.s_DeltaTime;
    }

    //根据结束时间获得剩余时间
    /**
     * 
     * @param endTime 毫秒
     */
    static leftTime(endTime) {
        if (endTime == 0) {
            return 0;
        }
        let dis = endTime - this.now();
        return dis;
    }

    static startTime(startTime) {
        return this.now() - startTime;
    }


    //返回本地时间(精确到毫秒的时间戳)
    static localNow() {
        let now = Date.now();
        // cc.log(" now =================================== "+now);
        return now;
    }

    //是否同一天
    static isOneDay(timestamp, now?) {
        let d: Date = this.timestamp2DateObj(timestamp);
        let d2: Date;
        if (!now) {
            now = Date.now();
        }
        d2 = this.timestamp2DateObj(now);

        return d.getDate() == d2.getDate() //d.getFullYear() == d2.getFullYear() && d.getMonth() == d2.getMonth() && 
    }

    static getPastTimestamp(timestamp) {
        let dis = this.now() - timestamp;
        return dis;
    }

    /**
     * 获取过去了多少天
     * @param timestamp 登录时的时间
     */
    static getPastDayNum(timestamp) {
        let now = this.now();
        let past = now - timestamp;
        return Math.floor(past / 1000 / 3600 / 24);
    }

    /**
     * 根据时间戳 推算 当前给定时间的时间戳。
     * @param timestamp  毫秒
     * @param hour 
     * @param munite 
     * @param second 
     */
    static getDayTime(timestamp: number, hour: number, munite: number = 0, second: number = 0) {
        let cDate = new Date(timestamp);
        let date2 = new Date(cDate.getFullYear(), cDate.getMonth(), cDate.getDate(), hour, munite, second);
        return date2.getTime();
    }

    /**
 * 获取过去了多少分钟
 * @param timestamp 登录时的时间
 */
    static getPastMinutesNum(timestamp) {
        return Math.floor(this.getPastSecondNum(timestamp) / 60);
    }

    static getPastSecondNum(timestamp) {
        let now = this.now();
        let past = now - timestamp;
        return Math.floor(past / 1000);
    }


    /**
     * 获得当地的时间
     * @param timestamp 服务器传递的时间戳 毫秒
     */
    static getLocalDateByTime(timestamp): Date {
        let d = this.Timestamp2Date(timestamp, this.s_ServerTimeZone, this.s_CurTimeZone);
        return d;
    }


    /**
     * 
     * @param date 
     */
    static getDateString(date: Date) {
        let year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate()
        // cc.log(" date ",date.toLocaleString());
        // cc.log(" date ",date.toLocaleDateString());
        // cc.log(" date ",date.toLocaleTimeString());
        return year + "/" + month + "/" + day;
    }


    /**
     * 
     * @param str "2018-12-5 06:00"
     */
    static getLocalDateByString(str) {

        let d = this.timestamp2DateObj(str);
        return this.Timestamp2Date(d.getTime(), this.s_ServerTimeZone, this.s_CurTimeZone);
    }

    /**
     * 
     * @param num 
     */
    static timestamp2DateObj(num: number): Date {
        let date: Date = new Date(num)
        return date;
    }

    /**
     * 返回以timestamp计算的, 所在目标时区的Date对象
     * 默认destTimeZone为本地时区
     * 注意参数 timestamp 需要必须精确到 毫秒！
     * 如果timestamp 是服务器的时间戳，curTimeZzone 应该是服务器的时区。
     * @param timestamp curTimeZzone 的时间戳 
     * @param curTimeZzone 当前的时区
     * @param destTimeZone 目标时区
     */
    static Timestamp2Date(timestamp, curTimeZzone, destTimeZone) {
        if (!destTimeZone) {
            destTimeZone = curTimeZzone;
        }
        //当前时区比目标时区多出的时区数
        let deltaTimeZone = curTimeZzone - destTimeZone;
        let deltaTime = deltaTimeZone * 3600000;
        let adjustedNow = timestamp - deltaTime;

        return new Date(adjustedNow);
    }


    //返回以Now()为时间戳计算的, 所在目标时区的Date对象
    static NowDate(destTimeZone) {
        return this.Timestamp2Date(this.now(), this.s_CurTimeZone, destTimeZone);
    }

    /**
     * 判断是否可以刷新。
     * @param sTime 上次刷新时间 毫秒 
     * @param time 给定刷新时间  
     */
    static lessThenTime(sTime, hour, minute: number = 0, second: number = 0) {
        if (sTime == 0) {
            return true;
        }
        let sDate = new Date(sTime);
        // console.log(sDate.toLocaleString());
        let cDate = new Date(this.now());
        // cc.log(" cDate.getFullYear()",cDate.getFullYear(),cDate.getDate());
        // console.log(cDate.toLocaleString());
        let fiveDate = new Date(cDate.getFullYear(), cDate.getMonth(), cDate.getDate(), hour, minute, second);
        // console.log(fiveDate.toLocaleDateString());
        // console.log(fiveDate.toLocaleString());
        // console.log(fiveDate.getTime());
        return sDate.getTime() < fiveDate.getTime();
    }

    static moreThenTime(sTime, hour, minute: number = 0, second: number = 0) {
        if (sTime == 0) {
            return true;
        }
        let sDate = new Date(sTime);
        // console.log(sDate.toLocaleString());
        let cDate = new Date(this.now());
        // cc.log(" cDate.getFullYear()",cDate.getFullYear(),cDate.getDate());
        // console.log(cDate.toLocaleString());
        let temp = new Date(cDate.getFullYear(), cDate.getMonth(), cDate.getDate(), hour, minute, second);
        // console.log(temp.toLocaleString());
        return sDate.getTime() > temp.getTime();
    }

    static isBetween(sTime, hour1: number, hour2: number) {
        if (sTime == 0) {
            return false;
        }
        // console.log(' isBetween start ')
        let sDate = new Date(sTime);
        // console.log(sDate.toLocaleString());
        let cDate = new Date(this.now());
        // cc.log(" cDate.getFullYear()",cDate.getFullYear(),cDate.getDate());
        // console.log(cDate.toLocaleString());
        let data1 = new Date(cDate.getFullYear(), cDate.getMonth(), cDate.getDate(), hour1, 0, 0);
        // console.log(data1.toLocaleString());
        let data2 = new Date(cDate.getFullYear(), cDate.getMonth(), cDate.getDate(), hour2, 0, 0);
        // console.log(data2.toLocaleString());
        // console.log(' isBetween end ')
        return sDate.getTime() <= data2.getTime() && sDate.getTime() >= data1.getTime();
    }








    /**
     * 获取登陆天数
     * @param regTime  登陆时间
     * @param refreshTime 刷新时间
     */
    static getLoginDayNum(regTime: number, refreshTime: number) {


        let t0 = this.getDayTime(regTime, refreshTime);

        let t = this.getDayTime(this.now(), refreshTime);

        return Math.ceil((t - t0 + 1) / 86400000);
    }


    //-------------------------------

    // static test(){
    //     let d = new Date();

    //     let od = this.Timestamp2Date(d.getTime(),this.s_CurTimeZone, 9);

    //     cc.log(" time 1 ",od.toLocaleDateString());
    //     cc.log(" time 2 ",od.toLocaleString());
    //     cc.log(" time 3 ",od.toLocaleTimeString());

    // var d=new Date(); //创建一个Date对象
    // var localTime = d.getTime();
    // var localOffset=d.getTimezoneOffset()*60000; //获得当地时间偏移的毫秒数
    // var utc = localTime + localOffset; //utc即GMT时间

    // cc.log(" localTime ",localTime," localOffset ",localOffset," utc ",utc," d.getTimezoneOffset() ",d.getTimezoneOffset());

    // var offset =10; //以夏威夷时间为例，东10区

    // var hawaii = utc + (3600000*offset); 
    // cc.log(" hawaii ",hawaii);
    // var nd = new Date(hawaii); 
    // cc.log("Hawaii time is " , nd.toLocaleString());        
    // }



    // //时间戳换算为总毫秒数
    // static TotalMillisecond() {
    //     return this.now();
    // }

    // //时间戳换算为总秒数
    // static TotalSeconds() {
    //     return Math.floor(this.now() / 1000);
    // }

    // //时间戳换算为总分钟数
    // static TotalMinutes() {
    //     return Math.floor(this.now() / (1000 * 60));
    // }

    // //时间戳换算为总小时数
    // static TotalHours() {
    //     return Math.floor(this.now() / (1000 * 60 * 60));
    // }

    // //时间戳换算为总天数
    // static TotalDays() {
    //     return Math.floor(this.now() / (1000 * 60 * 60 * 24));
    // }

    // //时间戳换算为总月数, TODO, 要怎么算？
    // static TotalMonths() {
    //     cc.error("暂未实现");
    // }    


}
